package jp.sourceforge.akjrcp.psp.imageconvert;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;

import javax.imageio.ImageIO;

import org.apache.commons.io.FilenameUtils;

import jp.sourceforge.akjrcp.util.FileNameUtils;
import jp.sourceforge.akjrcp.util.image.ImageUtils;

public abstract class AbstractImageChanger implements SupportCancel,ImageChanger{

	protected int width = 480;
	protected int height = 272;
	protected long time;
	protected float jpegQuality = 1.0f;
	protected boolean cancel;

	protected ImageLoader imageLoader=new ImageLoader();
	
	public BufferedImage toARGB(BufferedImage img) {
		BufferedImage ret=new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_INT_ARGB);
			ret.getGraphics().drawImage(img,0,0,null);
			
		return ret;
	}
	
/**
 * @deprecated nevet change and size change.
 * @param img
 * @param width
 * @param height
 * @return
 */
	public BufferedImage toARGB(BufferedImage img,int width,int height) {
		BufferedImage ret=new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
		
		Graphics2D g2=(Graphics2D) ret.getGraphics();
		g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g2.drawImage(img, 0, 0, width, height,0, 0, img.getWidth(), img.getHeight(),  null);
		return ret;
	}
	
	/**
	 * @deprecated nevet change and size change.
	 * @param img
	 * @param width
	 * @param height
	 * @return
	 */
	public BufferedImage toRGB(BufferedImage img,int width,int height) {
		BufferedImage ret=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
		
		Graphics2D g2=(Graphics2D) ret.getGraphics();
		g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		g2.drawImage(img, 0, 0, width, height,0, 0, img.getWidth(), img.getHeight(),  null);
		return ret;
	}

	public BufferedImage toRGB(BufferedImage img) {
		BufferedImage ret=new BufferedImage(img.getWidth(),img.getHeight(),BufferedImage.TYPE_INT_RGB);
			ret.getGraphics().drawImage(img,0,0,null);
			
		return ret;
	}
	
	protected void saveImage(BufferedImage clipImage,String imageFileName, File exportDir) throws IOException {
		String extension="png";
		if(ImageUtils.isJpegFile(imageFileName)){
			extension="jpg";
		}
		File newFile=new File(exportDir,FileNameUtils.getRemovedExtensionName(FileNameUtils.getZipEntryFileName(imageFileName))+"."+extension);
		if(extension.equals("jpg")){
			ImageUtils.writeJpegWithQuality(clipImage, newFile, jpegQuality);	
		}else{
			ImageIO.write(clipImage, extension, newFile);
		}
		newFile.setLastModified(time);//time is very important
		time+=2000;//better 2s,because 1s sometime got problem
	}

	protected void saveImage(BufferedImage clipImage, int index, String imageFileName, File exportDir) throws IOException {
		String extension="png";
		if(ImageUtils.isJpegFile(imageFileName)){
			extension="jpg";
		}
		File newFile=new File(exportDir,FileNameUtils.getRemovedExtensionName(FileNameUtils.getZipEntryFileName(imageFileName))+"_"+FileNameUtils.digited(index,3)+"."+extension);
		if(newFile.exists()){
			//never overwrite
			newFile=FileNameUtils.makeBackupFileWithHeader(newFile,"_");
			}
		if(extension.equals("jpg")){
		ImageUtils.writeJpegWithQuality(clipImage, newFile, jpegQuality);	
		}else{
		ImageIO.write(clipImage, extension, newFile);
		}
		boolean ret=newFile.setLastModified(time);//time is very important
		
		time+=2000;//better 2s,because 1s sometime got problem
		if(ret==false){
			throw new IOException("last-modified:faild");
		}
		
	}
	
	protected void saveImage(BufferedImage clipImage, File imageFile, File exportDir) throws IOException {
		String extension="png";
		if(imageFile.getName().toLowerCase().endsWith(".jpg")){
			extension="jpg";
		}
		File newFile=new File(exportDir,FileNameUtils.getRemovedExtensionName(imageFile.getName())+"."+extension);

		if(extension.equals("jpg")){
		//image type is rgb is better?
		ImageUtils.writeJpegWithQuality(toRGB(clipImage), newFile, jpegQuality);	
		}else{
		ImageIO.write(clipImage, extension, newFile);
		}
		newFile.setLastModified(time);//time is very important
		time+=2000;//better 2s,because 1s sometime got problem
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public int getWidth() {
		return width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public float getJpegQuality() {
		return jpegQuality;
	}

	public void setJpegQuality(float jpegQuality) {
		this.jpegQuality = jpegQuality;
	}

	public boolean isCancel() {
		return cancel;
	}

	public void setCancel(boolean cancel) {
		this.cancel = cancel;
	}
	
	public void writePng(BufferedImage clipImage, int index, String imageFileName, File exportDir) throws IOException {
		String extension="png";
		
		File newFile=new File(exportDir,FileNameUtils.getRemovedExtensionName(imageFileName)+"_"+FileNameUtils.digited(index,3)+"."+extension);
		
		ImageIO.write(clipImage, extension, newFile);
		
		newFile.setLastModified(time);//time is very important
		time+=2000;//better 2s,because 1s sometime got problem
	}
	
	public void clear(){
		imageLoader.clear();
	}

	protected static class ImageLoader {
		private BufferedImage image;
		private long lasttime;
		private String lastPath;

		protected void clear(){
			image.getGraphics().dispose();
			image=null;
			
			System.gc();
		}
		protected BufferedImage loadImage(String path) throws IOException{
			if(image==null){
				File file=new File(path);
				image=ImageIO.read(file);
				lastPath=path;
				lasttime=file.lastModified();
			}else{
				File file=new File(path);
				if(path.equals(lastPath) && file.lastModified()==lasttime){
					return image;//return cache one
				}else{
					image=ImageIO.read(file);
					lastPath=path;
					lasttime=file.lastModified();
				}
			}
			
			return image;
		}
		protected BufferedImage loadImage(String path,InputStream input) throws IOException{
			if(image==null){
				image=ImageIO.read(input);
				lastPath=path;
			}else{
				
				if(path.equals(lastPath)){
					return image;//return cache one
				}else{
					image=ImageIO.read(input);
					lastPath=path;
				}
			}
			
			return image;
		}
		

	}
}
